<?php
/**
 * Created by PhpStorm.
 * User: jochen
 * Date: 2017/1/12
 * Time: 下午5:44
 */

namespace App\Plugins;


class Plugin
{
    const FILE_PATH = 'app/plugins.json';
    protected $plugins;

    public function __construct()
    {
        $file = storage_path(static::FILE_PATH);
        if (file_exists($file)) {
            $this->plugins = json_decode(file_get_contents($file));
            if (json_last_error()) {
                assert(false, json_last_error_msg());
            }
        } else {
            $this->plugins = new \stdClass();
        }
    }

    /**
     * 安装插件
     * @param $pluginName
     * @param $namespace
     * @param $provider
     */
    public function install($pluginName, $namespace, $provider)
    {
        assert(!empty($pluginName), '插件名称不能为空');
        assert(!empty($namespace), '命名空间不能为空');
        assert(!empty($provider), 'Provider类名不能为空');

        $pluginName = ucfirst($pluginName);

        $plugin = $this->newPlugin($namespace, $provider);

        if (isset($this->plugins->$pluginName)) {
            assert(false, '插件已存在，不可重复安装');
        }

        $this->plugins->$pluginName = $plugin;
        $this->save();
    }

    /**
     * 删除插件
     * @param $pluginName
     */
    public function remove($pluginName)
    {
        $pluginName = ucfirst($pluginName);
        if (isset($this->plugins->$pluginName)) {
            unset($this->plugins->$pluginName);
            $this->save();
        }
    }

    public function register($pluginName, $alias)
    {
        assert(isset($this->plugins->$pluginName), '插件不存在');
        if (!in_array($alias, $this->plugins->$pluginName->alias)) {
            array_push($this->plugins->$pluginName->alias, $alias);
        }
        $this->save();
    }

    public function pluginInfo($pluginName)
    {
        $name = ucfirst($pluginName);
        return $this->plugins->$name ?? null;
    }

    public function plugins()
    {
        $list = [];
        foreach ($this->plugins as $name => $plugin) {
            array_push($list, $name);
        }
        return $list;
    }

    public function findByAlias($alias)
    {
        foreach ($this->plugins as $plugin) {
            if (in_array(strtolower($alias), $plugin->alias)) {
                return $plugin;
            }
        }
        return null;
    }

    public function findByName($name)
    {
        $name = ucfirst($name);
        if(isset($this->plugins->$name)) {
            return $this->plugins->$name;
        }
        return null;
    }

    protected function save()
    {
        if (!empty($this->plugins)) {
            $raw = json_encode($this->plugins, 256);
            file_put_contents(storage_path(static::FILE_PATH), $raw);
        }
    }

    protected function newPlugin($namespace, $provider)
    {
        $plugin = new \stdClass();
        $plugin->namespace = str_replace('/', '\\', $namespace);
        $plugin->provider = $provider;
        $plugin->alias = [];
        return $plugin;
    }
}